﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MyWebPagesStarterKit.Controls;
using MyWebPagesStarterKit;
using System.Data;
using MyWebPagesStarterKit.Rewriter;
using System.Collections;

public partial class SectionControls_RBlog : SectionControlBaseClass
{
    private RBlog _section;
    private string glbComment, glbComments, glbAuthor;

    protected void Page_Load(object sender, EventArgs e)
    {
        glbComment = Resources.StringsRes.ctl_Blog_Comment;
        glbComments = Resources.StringsRes.ctl_Blog_Comments;
        glbAuthor = Resources.StringsRes.ctl_Blog_CommentsAuthor;
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        updateViews();
    }

    protected void Action(object sender, CommandEventArgs e)
    {
        switch (e.CommandName)
        {
            case "add_post":
                if (string.IsNullOrEmpty(txtTitle.Text))
                    return;
                AddPost();
                break;
            case "edit_post":
                ViewState["Edit"] = gvPosts.DataKeys[int.Parse(e.CommandArgument.ToString())].Value;
                btnAddTag.Enabled = (ViewState["Edit"] != null);
                EditPost();
                break;
            case "delete_post":
                _section.Entries.Rows.Remove(_section.GetEditEntryReadOnly(gvPosts.DataKeys[int.Parse(e.CommandArgument.ToString())].Value.ToString()));
                _section.Entries.AcceptChanges();
                _section.SaveData();
                break;
            case "add_tag":
                btnAddTag.Enabled = (ViewState["Edit"] != null);
                AddTag();
                break;
            case "add_comment":
                AddComment();
                break;
            case "delete_comment":
                DeleteComment(gwComment.DataKeys[int.Parse(e.CommandArgument.ToString())].Value.ToString());
                break;
        }
    }

    //Authors link in comments
    protected string GetLink(string id)
    {
        DataRow row = _section.GetEditEntryReadOnly(Request["details"]);

        List<RBlog.Comment> comments = new List<RBlog.Comment>();
        if (!DBNull.Value.Equals(row["Comments"]))
            comments = ((List<RBlog.Comment>)(row["Comments"]));

        RBlog.Comment comment = comments.Find(delegate(RBlog.Comment s) { return s.ID == id; });

        if (comment != null)
        {
            string name = string.Empty;
            if (string.IsNullOrEmpty(comment.Author) || (comment.Author == "Anonymous"))
                name = "Anonymous";
            else
                name = comment.Author;

            if (string.IsNullOrEmpty(comment.AuthorsBlog))
                return name;

            return string.Format("<a href=\"{0}\" target=\"_blank\">{1}</a> said:", Convert.ToString(comment.AuthorsBlog), name, Resources.StringsRes.ctl_Blog_Says);
        }
        
        return string.Empty;
    }

    //Edit a post
    private void EditPost()
    {
        if (ViewState["Edit"] != null)
        {
            string id = Convert.ToString(ViewState["Edit"]);
            LoadTags();
            DataRow row = _section.GetEditEntryReadOnly(id);
            txtTitle.Text = Convert.ToString(row["Title"]);
            txtHtml.Text = Convert.ToString(row["Html"]);
            txtDescription.Text = Convert.ToString(row["Description"]);
            List<RBlog.Tags> listTag = ((List<RBlog.Tags>)row["Tags"]);
            
            if (listTag != null)
            {
                if (listTag.Count > 0)
                {
                    foreach (RBlog.Tags tag in listTag)
                    {
                        chkTags.Items.FindByText(tag.Name).Selected = true; 
                    }
                }
            }
        }
        LoadComments();
    }


    #region comment

    private void LoadComments()
    {
        if(ViewState["Edit"] !=null)
        {
            gwComment.DataSource = null;
            DataRow row = _section.GetEditEntryReadOnly(Convert.ToString(ViewState["Edit"]));

            if (!DBNull.Value.Equals(row["Comments"]))
            {
                List<RBlog.Comment> comments = ((List<RBlog.Comment>)row["Comments"]);
                gwComment.DataSource = comments;
                gwComment.DataBind();
            }
        }

    }

    protected string GetHtml(string id)
    {
        if (ViewState["Edit"] != null)
        {
            DataRow row = _section.GetEditEntryReadOnly(Convert.ToString(ViewState["Edit"]));

            if (!DBNull.Value.Equals(row["Comments"]))
            {
                List<RBlog.Comment> comments = ((List<RBlog.Comment>)row["Comments"]);

                RBlog.Comment com = comments.Find(delegate (RBlog.Comment c) { return c.ID == id; });
                if (com != null)
                {
                    string text = com.Html;
                    if (text.Length > 80)
                        text = text.Substring(0,80);
                    return text;
                }
                
            }
        }
        return "No data added";
    }

    private void DeleteComment(string id)
    {
        if (ViewState["Edit"] != null && (!string.IsNullOrEmpty(id)))
        {
            DataRow row = _section.GetEditEntryReadOnly(Convert.ToString(ViewState["Edit"]));
            List<RBlog.Comment> comments = ((List<RBlog.Comment>)row["Comments"]);
            
            if (!DBNull.Value.Equals(row["Comments"]))
            {
                RBlog.Comment com = comments.Find(delegate(RBlog.Comment c) { return c.ID == id; });
                comments.Remove(com);
                row.AcceptChanges();
                _section.SaveData();
                LoadComments();
            }
        }
    }

    #endregion

    //Loads all tags
    private void LoadTags()
    {
        chkTags.Items.Clear();
        SortedList list = new SortedList();
        foreach (DataRow row in _section.Entries.Rows)
        {
            List<RBlog.Tags> tags = ((List<RBlog.Tags>)row["Tags"]);
            foreach (RBlog.Tags tag in tags)
            {
                if (!list.ContainsKey(tag.Name))
                {
                    list.Add(tag.Name, tag.Name);
                    chkTags.Items.Add(new ListItem(tag.Name, tag.Name));
                }
            }
        }
    }

    //Adds a tag (editView)
    private void AddTag()
    {
        if (ViewState["Edit"] != null)
        {
            DataRow row = _section.GetEditEntryReadOnly(Convert.ToString(ViewState["Edit"]));
            List<RBlog.Tags> tags = ((List<RBlog.Tags>)row["Tags"]);

            RBlog.Tags tag = new RBlog.Tags();
            tag.Name = txtTag.Text;
            tag.Count = 1;
            tags.Add(tag);
            row.AcceptChanges();
            _section.SaveData();

            EditPost();
        }
    }


    private void AddPost()
    {
        DataRow row = null;
        if (ViewState["Edit"] == null)
        {
            row = _section.Entries.NewRow();
            row["Guid"] = Guid.NewGuid();
            _section.Entries.Rows.Add(row);
            row["DateUpdated"] = DateTime.Now;
        }
        else
        {
            row = _section.GetEditEntryReadOnly(Convert.ToString(ViewState["Edit"]));
        }
        row["Title"] = txtTitle.Text;
        row["Html"] = txtHtml.Text;
        row["DateCreated"] = DateTime.Now;
        row["Created"] = DateTime.Now.ToShortDateString();

        List<RBlog.Tags> listTag = new List<RBlog.Tags>();

        foreach (ListItem item in chkTags.Items)
        {
            if (item.Selected)
            {
                RBlog.Tags tag = new RBlog.Tags();
                tag.Name = item.Text;
                tag.Count = 1;
                tag.Description = txtDescription.Text;
                listTag.Add(tag);
            }
        }
        row["Tags"] = listTag;
        row["RewriteUrl"] = string.Format("{0}.aspx", TextFormatter.CreateFriendlyUrl(txtTitle.Text)).ToLower();

        //For now
        string keywords = TextFormatter.RemoveHtmlTags(txtHtml.Text);
        if (keywords.Length > 100)
            keywords = keywords.Substring(0,100);
        row["keywords"] = txtTitle.Text + "," + keywords.Replace(" ", ",");
        row["Description"] = txtDescription.Text;
        
        
        row.AcceptChanges();
        _section.SaveData();

        ViewState["Edit"] = row["Guid"];

        EditPost();
    }

    private void AddComment()
    {
        string postID = Request.Params["details"];
        DataRow row = _section.GetEditEntryReadOnly(postID);

        List<RBlog.Comment> comments = new List<RBlog.Comment>();
        
        if (!DBNull.Value.Equals(row["Comments"]))
            comments = ((List<RBlog.Comment>)(row["Comments"]));

        RBlog.Comment comment = new RBlog.Comment();
        comment.ID = Guid.NewGuid().ToString();

        if (!string.IsNullOrEmpty(txtCommentAuthor.Text))
            comment.Author = txtCommentAuthor.Text;
        else
            comment.Author = "Anonymous";

        if (Page.User.Identity.IsAuthenticated)
            comment.Author = Page.User.Identity.Name;

        if (!string.IsNullOrEmpty(txtCommentWebsite.Text))
        {
            if (txtCommentWebsite.Text.ToLower().StartsWith("http://"))
            {
                if(txtCommentWebsite.Text.ToLower() != "http://")
                    comment.AuthorsBlog = txtCommentWebsite.Text.ToLower();
                else
                    comment.AuthorsBlog = string.Empty;
            }
        }
        

        comment.DateCreated = DateTime.Now.ToString();
        comment.Html = TextFormatter.RemoveHtmlTags(txtComment.Text);
        comments.Insert(0,comment);
        
        row["Comments"] = comments;

        _section.Entries.AcceptChanges();
        _section.SaveData();

        sendPing(row);

        Response.Redirect(Request.RawUrl);
    }

    private void LoadPosts()
    {
        gvPosts.DataSource = null;
        gvPosts.DataSource = _section.Entries;
        gvPosts.DataBind();
    }

    private void updateViews()
    {
        if (ViewMode == ViewMode.Edit)
        {
            multiview.SetActiveView(editView);
            btnAddTag.Enabled = (ViewState["Edit"] != null);
            LoadPosts();
           
        }
        else
        {
            if (Request["details"] != null)
            {
                multiview.SetActiveView(commentView);

                DataRow row =  _section.GetEditEntryReadOnly(Request["details"]);

                litDateCreated.Text = Convert.ToDateTime(row["DateCreated"]).ToLongDateString();
                litTitle.Text = Convert.ToString(row["Title"]);
                litHtml.Text = Convert.ToString(row["Html"]);

                SectionHeaderUtils.GenerateMeta(this.Page, Convert.ToString(row["Title"]), (string)row["Description"], (string)row["Keywords"]);
                litCommentsCount.Text = "0";

                if (!DBNull.Value.Equals(row["Comments"]))
                {
                    List<RBlog.Comment> comments = ((List<RBlog.Comment>)(row["Comments"]));
                    if (comments.Count > 0)
                    {
                        litCommentsCount.Text = comments.Count.ToString();
                        gvComments.DataSource = comments;
                        gvComments.DataBind();
                    }                    
                }

                if (!DBNull.Value.Equals(row["Tags"]))
                {
                    List<RBlog.Tags> tags = ((List<RBlog.Tags>)(row["Tags"]));

                    if (tags != null)
                    {
                        foreach (RBlog.Tags item in tags)
                            litTags.Text += string.Format("<a href=\"{0}?tag={1}\">{1}</a> ", new WebPage(WebPage.Current.PageId).VirtualPath.Replace("~", ""), item.Name);
                    }
                }
            }
            else
            {
                if (Request.Params["date"] != null)
                    ReloadByDate();
                else if (Request.Params["tag"] != null)
                    ReloadFromTags(Request.Params["tag"]);
                else
                    Reload();

                multiview.SetActiveView(readonlyView);
                
            }
        }
    }

    protected string GetTags()
    {
        string t = string.Empty;

        DataRow row = _section.GetEditEntryReadOnly(Request["details"]);

        if (!DBNull.Value.Equals(row["Tags"]))
        {
            List<RBlog.Tags> tags = ((List<RBlog.Tags>)(row["Tags"]));

            if (tags != null)
            {
                foreach (RBlog.Tags item in tags)
                    t += string.Format("<a href=\"{0}?tag={1}\">{1}</a> ", new WebPage(WebPage.Current.PageId).VirtualPath.Replace("~", ""), item.Name);
            }
        }

        return t;
    }

    protected string Counted(object id)
    {
        DataRow row = _section.GetEditEntryReadOnly(Convert.ToString(id));
        if (!DBNull.Value.Equals(row["Comments"]))
        {
            List<RBlog.Comment> comments = ((List<RBlog.Comment>)(row["Comments"]));
            
            string text = string.Empty;

            if (comments.Count > 1)
                text = string.Format(" ({0}) {1}", comments.Count.ToString(), glbComments);
            else if (comments.Count == 1)
                text = string.Format(" (1) {0}", glbComment);
            else
                text = string.Format(" (0) ", glbComments);

            return text;
        }
        return string.Format(" (0) {0}", glbComments);
    }

    protected string GetTags(object id)
    {
        string t = string.Empty;
        try
        {
            DataRow row = _section.GetEditEntryReadOnly(id.ToString());

            if (!DBNull.Value.Equals(row["Tags"]))
            {
                List<RBlog.Tags> tags = ((List<RBlog.Tags>)(row["Tags"]));

                if (tags != null)
                {
                    foreach (RBlog.Tags item in tags)
                        t += string.Format("<a href=\"{0}?tag={1}\">{1}</a> ", new WebPage(WebPage.Current.PageId).VirtualPath.Replace("~", ""), item.Name);
                }
            }
        }
        catch { }
        return t;
    }


    //Get all tagged posts
    private void ReloadFromTags(string t)
    {
        DataTable newlist = _section.Entries.Copy();
        newlist.DefaultView.Sort = "DateCreated DESC";

        DataTable db = new DataTable();
        
        DataColumn primaryKeyColumn = new DataColumn("Guid", typeof(Guid));
        primaryKeyColumn.Unique = true;

        db.Columns.Add(primaryKeyColumn);
        db.PrimaryKey = new DataColumn[] { primaryKeyColumn };

        db.Columns.AddRange(
            new DataColumn[] 
                {
                    new DataColumn("Title", typeof(string)),
                    new DataColumn("Html", typeof(string)),
                    new DataColumn("DateCreated", typeof(DateTime)),
                    new DataColumn("DateUpdated", typeof(DateTime)),
                    new DataColumn("Comments",typeof(List<MyWebPagesStarterKit.RBlog.Comment>)),
                    new DataColumn("Tags",typeof(List<MyWebPagesStarterKit.RBlog.Tags>)),
                    new DataColumn("RewriteUrl",typeof(string)),
                    new DataColumn("Keywords",typeof(string)),
                    new DataColumn("Description",typeof(string))
                }
       );

        foreach (DataRow row in newlist.Rows)
        {
            
            if (row["Tags"] != null)
            {
                List<RBlog.Tags> tags = ((List<RBlog.Tags>)(row["Tags"]));
                foreach (RBlog.Tags tag in tags)
                {
                    if (tag.Name == t)
                    {
                        db.ImportRow(row);
                        db.AcceptChanges();
                        break;
                    }
                }
           }
        }

        db.GetChanges();
        db.DefaultView.Sort = "DateCreated DESC";

        PagedDataSource data = new PagedDataSource();
        data.DataSource = db.DefaultView;

        data.AllowPaging = true;
        data.PageSize = 5;
        data.CurrentPageIndex = CurrentPage;

        bprev.Visible = !data.IsFirstPage;
        bnext.Visible = !data.IsLastPage;

        lstBlogEntries.DataSource = data;
        lstBlogEntries.DataBind();
    }

    private void Reload()
    {
        DataTable dt = _section.Entries;
        dt.DefaultView.Sort = "DateCreated DESC";

        PagedDataSource data = new PagedDataSource();
        data.DataSource = dt.DefaultView;

        data.AllowPaging = true;
        data.PageSize = 5;
        data.CurrentPageIndex = CurrentPage;

        bprev.Visible = !data.IsFirstPage;
        bnext.Visible = !data.IsLastPage;

        lstBlogEntries.DataSource = data;
        lstBlogEntries.DataBind();
    }

    private void ReloadByDate()
    {
        DataView dt = _section.GetEntriesReadonlyByDate(Convert.ToDateTime(Request.Params["date"]));
        dt.Sort = "Created DESC";

        PagedDataSource data = new PagedDataSource();
        data.DataSource = dt;

        data.AllowPaging = true;
        data.PageSize = 5;
        data.CurrentPageIndex = CurrentPage;

        bprev.Visible = !data.IsFirstPage;
        bnext.Visible = !data.IsLastPage;

        lstBlogEntries.DataSource = data;
        lstBlogEntries.DataBind();
    }

    public int CurrentPage
    {
        get
        {
            // look for current page in ViewState
            object o = this.ViewState["_CurrentPage"];

            if (o == null)
            {
                return 0; // default page index of 0
            }
            else
            {
                int c =(int)o;
                if(c>0)
                    return (int)o;
                else
                    return 0;
            }
        }

        set
        {
            this.ViewState["_CurrentPage"] = value;
        }
    } 

    protected void cmdPrev_Click(object sender, System.EventArgs e)
    {
        // Set viewstate variable to the previous page
        CurrentPage -= 1;

        // Reload control
        if (Request.Params["tag"] != null)
            ReloadFromTags(Request.Params["tag"]);
        else
            Reload();
    }

    protected void cmdNext_Click(object sender, System.EventArgs e)
    {
        // Set viewstate variable to the next page
        CurrentPage += 1;

        // Reload control
        if (Request.Params["tag"] != null)
            ReloadFromTags(Request.Params["tag"]);
        else
            Reload();
    } 

    private void sendPing(DataRow row)
    {
        WebLogPing.PingWeblogsCom(Context, 
                Convert.ToString(row["Title"]),
                GetPrefix(Convert.ToString(row["RewriteUrl"])), 
                true
        );
    }


    public override bool HasAdminView
    {
        get { return true; }
    }

    public override string InfoUrl
    {
        get { return ""; }
    }

    public override ISection Section
    {
        set
        {
            if (value is RBlog)
                _section = (RBlog)value;
            else
                throw new ArgumentException("Section must be of type RBlog");
        }
        get { return _section; }
    }

    /// <summary>
    /// Adds date and url
    /// </summary>
    /// <param name="link">The link to perform rewrite prefix to.</param>
    /// <returns>A browserfriendly url</returns>
    protected string GetPrefix(string link)
    {
        return string.Format("{0}{1}/{2}", SectionRewriter.GetPrefix(_section.GetType().Name),DateTime.Now.ToShortDateString(), link).ToLower();
    }
}
